package com.lhy.framework.beans.factory.annotation;

import cn.hutool.core.bean.BeanUtil;
import com.lhy.framework.beans.BeansException;
import com.lhy.framework.beans.PropertyValues;
import com.lhy.framework.beans.factory.BeanFactory;
import com.lhy.framework.beans.factory.BeanFactoryAware;
import com.lhy.framework.beans.factory.ConfigurablelistableBeanFactory;
import com.lhy.framework.beans.factory.factory.InstantiationAwareBeanPostProcessor;
import com.lhy.framework.utils.ClassUtils;

import java.lang.reflect.Field;

/**
 * @Title:
 * @Description: 功能概述:
 * @Author: lihaiyang
 * @version: 1.0 .
 * @Date: 2022-09-14 15:37
 * @Copyright: Copyright(c)2022 RedaFlight.comAll Rights Reserved
 */
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {

    private ConfigurablelistableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (ConfigurablelistableBeanFactory) beanFactory;
    }

    @Override
    public Object postProcessBeforeInitialization(String beanName, Object bean) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(String beanName, Object bean) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessBeforeInstantiation(String beanName, Class<?> beanClass) throws BeansException {
        return null;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, String beanName, Object bean) {

        Class<?> clazz = bean.getClass();
        clazz = ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;

        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            // 1、处理注解 @Value
            Value valueAnnotation = field.getAnnotation(Value.class);
            if (null != valueAnnotation) {
                String value = valueAnnotation.value();
                value = beanFactory.resolveEmbeddedValue(value);
                BeanUtil.setFieldValue(bean, field.getName(), value);
            }

            // 2、处理注解 @Autowired
            Autowired autowiredAnnotation = field.getAnnotation(Autowired.class);
            if (null != autowiredAnnotation) {
                Class<?> fieldType = field.getType();
                String dependentBeanName = null;
                Qualifier qualifierAnnotation = field.getAnnotation(Qualifier.class);
                Object dependentBean = null;
                if (null != qualifierAnnotation) {
                    dependentBeanName = qualifierAnnotation.value();
                    dependentBean = beanFactory.getBean(dependentBeanName, fieldType);
                } else {
                    dependentBean = beanFactory.getBean(fieldType);
                }
                BeanUtil.setFieldValue(bean, field.getName(), dependentBean);
            }
        }
        return propertyValues;
    }
}
